home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / DropFTP / DLOG 129.c next >
Encoding:
Text File  |  1994-02-03  |  18.2 KB  |  720 lines  |  [TEXT/KAHL]

  1. host[256];
  2. extern char user[256];
  3. extern char pswd[256];
  4.         
  5. /* Symbolic Dialog Item Numbers */
  6.  
  7. static enum {
  8.     BUT1_OK = 1,
  9.     BUT2_Cancel,
  10.     EDIT3,
  11.     EDIT4,
  12.     EDIT5,
  13.     STXT6_Host,
  14.     STXT7_User,
  15.     STXT8_Password,
  16.     ICON9,
  17.     LASTITEM
  18.     };
  19.  
  20. #define OK_ITEM     BUT1_OK
  21. #define CANCEL_ITEM     BUT2_Cancel
  22.  
  23. /* Useful constants */
  24.  
  25. #ifndef ENTERkey
  26. #define ENTERkey    0x3
  27. #endif
  28. #ifndef DELETEkey
  29. #define DELETEkey    0x8
  30. #endif
  31. #ifndef NIL
  32. #define NIL ((void *)0)
  33. #endif
  34. #ifndef TRUE
  35. #define TRUE 1
  36. #endif
  37. #ifndef FALSE
  38. #define FALSE 0
  39. #endif
  40. #ifndef FRONT_WINDOW
  41. #define FRONT_WINDOW  ((WindowPtr) (-1L))
  42. #endif
  43.  
  44. /* Prototypes */
  45.  
  46.  
  47. DialogPtr OpenThisDialog(void);
  48. void      CloseThisDialog(DialogPtr dlog);
  49. void      DoDialogUpdate(DialogPtr dlog);
  50. void      DoDialogActivate(DialogPtr dlog, int activ);
  51. void      DoDialogContent(DialogPtr dlog, EventRecord *evt);
  52. int       DoDialogItem(DialogPtr dlog, short itemHit);
  53.  
  54. pascal  Boolean MyFilter(DialogPtr dlog, EventRecord *evt, short *itemHit);
  55. Boolean CheckUserItems(Point where, short *itemHit);
  56. int     AnyBadValues(DialogPtr dlog);
  57.  
  58. void    CenterWindow(WindowPtr w, int top);
  59. long    strlen(char *);
  60. char   *strcpy(char *dst, char *src);
  61. char   *PascalToC(char *pstr);
  62. char   *CToPascal(char *cstr);
  63. void    PutDlgString(DialogPtr dlog, int item, char *str, int sel);
  64. void    PutDlgWord(DialogPtr dlog, int item, int val, int sel);
  65. void    PutDlgLong(DialogPtr dlog, int item, long val, int sel);
  66. void    PutDlgChkRadio(DialogPtr dlog, int item, int val);
  67. int     GetDlgString(DialogPtr dlog, int item, char *str);
  68. int     GetDlgWord(DialogPtr dlog, int item, short *val);
  69. int     GetDlgLong(DialogPtr dlog, int item, long *val);
  70. int     GetDlgChkRadio(DialogPtr dlog, int item);
  71. int     TextSelected(DialogPtr dlog);
  72. OSType  CanPaste(int n, ...);
  73. void    FrameDefault(DialogPtr dlog, int item, int frame);
  74. void    GetDlgPanel(DialogPtr dlog, int item, Rect *panel);
  75.  
  76. static Point where;
  77. static int modifiers;
  78.  
  79. /*
  80.  *    Display this modal dialog.  Return TRUE if OK, FALSE if CANCEL or error.
  81.  *    If the dialog displays values from outside this module, you should either
  82.  *    import them from globals, or change the argument list of this routine to
  83.  *    bring them in and pass them to OpenThisDialog(), DoDialogItem(), etc.
  84.  */
  85.  
  86. int DoPrefs(char save)
  87.     {
  88.         short itemHit,okay,keepGoing=TRUE;
  89.         register DialogPtr dlog; GrafPtr oldPort;
  90.         extern WindowPtr    gSplashScreen;
  91.  
  92.         /* Build dialog window and install its item values */
  93.         
  94.         GetPort(&oldPort);
  95.         dlog = OpenThisDialog();
  96.         if (dlog == NIL) return(FALSE);
  97.  
  98.         /* Entertain filtered user events until dialog is dismissed */
  99.         
  100.         while (keepGoing) {
  101.             ModalDialog(MyFilter,&itemHit);
  102.             keepGoing = DoDialogItem(dlog,itemHit);
  103.             }
  104.         
  105.         /*
  106.          *    Do final processing of item values, such as exporting them to caller.
  107.          *    DoDialogItem() has already called AnyBadValues().
  108.          */
  109.         
  110.         if (okay = (itemHit==OK_ITEM)) {        /* Or whatever is equivalent */
  111.             
  112.             GetDlgString( dlog, EDIT3, host);
  113.             GetDlgString( dlog, EDIT4, user);
  114.             GetDlgString( dlog, EDIT5, pswd);
  115.             p2cstr((StringPtr)host);
  116.             p2cstr((StringPtr)user);
  117.             p2cstr((StringPtr)pswd);
  118.             if (save) WritePref();
  119.             if (gSplashScreen) {
  120.                 InvalRect(&gSplashScreen->portRect);    
  121.             }
  122.         }
  123.  
  124.         /* That's all, folks! */
  125.         
  126.         CloseThisDialog(dlog);
  127.         SetPort(oldPort);
  128.         
  129.         return(okay);
  130.     }
  131.  
  132. /*
  133.  *    We have to have a filter function, at the very least so that we can outline
  134.  *    any default button, entertain keyboard editing commands, cmd-period canceling, etc.
  135.  *    Note that you do not need to have a special user item covering the default button
  136.  *    in your dialog item list.
  137.  */
  138.  
  139. static pascal Boolean MyFilter(DialogPtr dlog, EventRecord *evt, short *itemHit)
  140.     {
  141.         Boolean ans=FALSE,doHilite=FALSE; WindowPtr w;
  142.         short type,ch; Handle hndl; Rect box;
  143.         static long then; static Point clickPt;
  144.         
  145.         w = (WindowPtr)(evt->message);
  146.         switch(evt->what) {
  147.             case updateEvt:
  148.                 if (w == dlog) {
  149.                     /* Update our dialog contents */
  150.                     DoDialogUpdate(dlog);
  151.                     ans = TRUE; *itemHit = 0;
  152.                     }
  153.                  else {
  154.                     /*
  155.                      *    Call your main event loop DoUpdate(w) routine here if you
  156.                      *    don't want unsightly holes in background windows caused
  157.                      *    by nested alerts, balloon help, or screen savers (see
  158.                      *    Tech Note #304).
  159.                      */
  160.                     }
  161.                 break;
  162.             case activateEvt:
  163.                 if (w == dlog) {
  164.                     DoDialogActivate(dlog,(evt->modifiers & activeFlag)!=0);
  165.                     *itemHit = 0;
  166.                     }
  167.                  else {
  168.                     /*
  169.                      *    Call your main event loop DoActivate(w) routine here if
  170.                      *    you want to deactivate the former frontmost window, in order
  171.                      *    to unhighlight any selection, scroll bars, etc.
  172.                      */
  173.                     }
  174.                 break;
  175.             case mouseDown:
  176.             case mouseUp:
  177.                 where = evt->where;        /* Make info available to DoDialog() */
  178.                 GlobalToLocal(&where);
  179.                 modifiers = evt->modifiers;
  180.                 ans = CheckUserItems(where,itemHit);
  181.                 break;
  182.             case keyDown:
  183.                 if ((ch=(unsigned char)evt->message)=='\r' || ch==ENTERkey) {
  184.                     *itemHit = OK_ITEM /* Default Item Number here */;
  185.                     doHilite = ans = TRUE;
  186.                     }
  187.                  else if (evt->modifiers & cmdKey) {
  188.                     ch = (unsigned char)evt->message;
  189.                     switch(ch) {
  190.                         case 'x':
  191.                         case 'X':
  192.                             if (TextSelected(dlog))
  193.                                 { SystemEdit(3); ZeroScrap(); DlgCut(dlog); TEToScrap(); }
  194.                              else {
  195.                                 /* Cut from anything else cuttable, like a list */
  196.                                 }
  197.                             break;
  198.                         case 'c':
  199.                         case 'C':
  200.                             if (TextSelected(dlog))
  201.                                 { SystemEdit(3); ZeroScrap(); DlgCopy(dlog); TEToScrap(); }
  202.                              else {
  203.                                 /* Copy from anything else copyable, like a list */
  204.                                 }
  205.                             break;
  206.                         case 'v':
  207.                         case 'V':
  208.                             if (CanPaste(1,'TEXT'))
  209.                                 { TEFromScrap(); DlgPaste(dlog); }
  210.                              else {
  211.                                  /* Deal with any other pasteable scraps here */
  212.                                 }
  213.                             break;
  214.                         case 'a':
  215.                         case 'A':
  216.                             if (((DialogPeek)dlog)->editField >= 0) {
  217.                                 /* Dialog has text edit item: select all */
  218.                                 SelIText(dlog,((DialogPeek)dlog)->editField+1,0,32767);
  219.                                 }
  220.                              else {
  221.                                 }
  222.                             *itemHit = 0;
  223.                             break;
  224.                         case '.':
  225.                             *itemHit = CANCEL_ITEM;
  226.                             doHilite = TRUE;
  227.                             break;
  228.                         }
  229.                     ans = TRUE;        /* Other cmd-chars ignored */
  230.                     }
  231.                 break;
  232.             }
  233.         if (doHilite) {
  234.             GetDItem(dlog,*itemHit,&type,&hndl,&box);
  235.             /* Reality check */
  236.             if (type == (btnCtrl+ctrlItem)) {
  237.                 long soon = TickCount() + 7;        /* Or whatever feels right */
  238.                 HiliteControl((ControlHandle)hndl,1);
  239.                 while (TickCount() < soon) ;        /* Leave hilited for a bit */
  240.                 }
  241.             }
  242.         return(ans);
  243.     }
  244.  
  245. /*
  246.  * Mouse down event:
  247.  * Check if it's in some user item, and convert to itemHit if appropriate.
  248.  */
  249.  
  250. static Boolean CheckUserItems(Point where, short *itemHit)
  251.     {
  252.         return(FALSE);
  253.     }
  254.  
  255. /*
  256.  * Redraw the contents of this dialog due to update event.
  257.  * If you have not installed UserItem draw routines, you should redraw
  258.  * them explicitly here; otherwise, UpdtDialog() will call your routines.
  259.  */
  260.  
  261. static void DoDialogUpdate(DialogPtr dlog)
  262.     {
  263.         GrafPtr oldPort;
  264.  
  265.         GetPort(&oldPort); SetPort(dlog);
  266.         BeginUpdate(dlog);
  267.  
  268.         UpdtDialog(dlog,dlog->visRgn);
  269.         FrameDefault(dlog,BUT1_OK,TRUE);
  270.  
  271.         EndUpdate(dlog);
  272.         SetPort(oldPort);
  273.     }
  274.  
  275. /*
  276.  * Activate event: Activate or deactivate this dialog and any items in it
  277.  */
  278.  
  279. static void DoDialogActivate(DialogPtr dlog, int activ)
  280.     {
  281.         SetPort(dlog);
  282.     }
  283.  
  284. /*
  285.  * Build this dialog's window on desktop, and install initial item values.
  286.  * Return the dlog opened, or NIL if error (no resource, no memory).
  287.  */
  288.  
  289. static DialogPtr OpenThisDialog()
  290.     {
  291.         short type; Handle hndl; Rect box; GrafPtr oldPort;
  292.         DialogPtr dlog; unsigned char *p,str[256];
  293.  
  294.                 
  295.         GetPort(&oldPort);
  296.         dlog = GetNewDialog(thisDialogID,NIL,FRONT_WINDOW);
  297.         if (dlog == NIL) { SysBeep(1); return(NIL); }    /* Poor man's error message */
  298.  
  299.         //CenterWindow(dlog,0);
  300.         SetPort(dlog);
  301.  
  302.         /* Fill in dialog's values here */
  303.  
  304.  
  305.         PutDlgString(dlog,EDIT4,(char *)c2pstr(user), FALSE);
  306.         p2cstr((StringPtr)user);
  307.         PutDlgString(dlog,EDIT5,(char *)c2pstr(pswd), FALSE);
  308.         p2cstr((StringPtr)pswd);
  309.         
  310.         PutDlgString(dlog,EDIT3,(char *)c2pstr(host), TRUE);
  311.         p2cstr((StringPtr)host);
  312.         
  313.         ShowWindow(dlog);
  314.         return(dlog);
  315.  
  316.     }
  317.  
  318. /*
  319.  * Clean up any allocated stuff, and return dialog to primordial mists
  320.  */
  321.  
  322. static void CloseThisDialog(DialogPtr dlog)
  323.     {
  324.         DisposDialog(dlog);    /* Call CloseDialog if you provide storage to GetNewDialog */
  325.     }
  326.  
  327. /*
  328.  * Deal with user clicking on an item in this dialog, either modal or non-modal.
  329.  * The local point is in where; modifiers in modifiers.
  330.  * Returns whether or not the dialog should be closed (keepGoing).
  331.  */
  332.  
  333. static int DoDialogItem(DialogPtr dlog, short itemHit)
  334.     {
  335.         short type,okay=FALSE,keepGoing=TRUE,val;
  336.         Handle hndl; Rect box; Point pt;
  337.         unsigned char *p,str[256];
  338.  
  339.         if (itemHit<1 || itemHit>=LASTITEM)
  340.             return(keepGoing);                /* Only legal items, please */
  341.  
  342.         GetDItem(dlog,itemHit,&type,&hndl,&box);
  343.         switch(type) {
  344.             case ctrlItem+btnCtrl:
  345.                 switch(itemHit) {
  346.                     case BUT1_OK:
  347.                         keepGoing = FALSE; okay = TRUE;
  348.                         break;
  349.                     case BUT2_Cancel:
  350.                         keepGoing = FALSE;
  351.                         break;
  352.                     }
  353.                 break;
  354.             case ctrlItem+chkCtrl:
  355.                 break;
  356.             case ctrlItem+radCtrl:
  357.                 break;
  358.             case ctrlItem+resCtrl:
  359.                 break;
  360.             case statText:
  361.                 switch(itemHit) {
  362.                     case STXT6_Host:        /* NOT Enabled */
  363.                         break;
  364.                     case STXT7_User:        /* NOT Enabled */
  365.                         break;
  366.                     case STXT8_Password:        /* NOT Enabled */
  367.                         break;
  368.                     }
  369.                 break;
  370.             case editText:
  371.                 switch(itemHit) {
  372.                     case EDIT3:
  373.                         break;
  374.                     case EDIT4:
  375.                         break;
  376.                     case EDIT5:
  377.                         break;
  378.                     }
  379.                 break;
  380.             case iconItem:
  381.                 switch(itemHit) {
  382.                     case ICON9:        /* NOT Enabled */
  383.                         break;
  384.                     }
  385.                 break;
  386.             case picItem:
  387.                 break;
  388.             case userItem:
  389.                 break;
  390.             }
  391.  
  392.         if (okay) keepGoing = AnyBadValues(dlog);
  393.         return(keepGoing);
  394.     }
  395.  
  396. /*
  397.  * Pull values out of dialog items and deliver TRUE if any of them are
  398.  * illegal or inconsistent; otherwise deliver FALSE.  If any values are bad,
  399.  * you should inform your user about the problem here before delivering TRUE.
  400.  * If any items are missing values, this is the place to assign any defaults.
  401.  */
  402.  
  403. static int AnyBadValues(DialogPtr dlog)
  404.     {
  405.         char str[256]; short val,len;
  406.  
  407.         if (GetDlgString(dlog,EDIT3,str)) {
  408.             /* Got a string (can also call GetDlgWord(), etc. here) */
  409.             }
  410.         else {
  411.             /* Field was empty */
  412.             }
  413.         if (GetDlgString(dlog,EDIT4,str)) {
  414.             }
  415.         else {
  416.             }
  417.         if (GetDlgString(dlog,EDIT5,str)) {
  418.             }
  419.         else {
  420.             }
  421.         return(FALSE);
  422.     }
  423.  
  424. /*••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••*/
  425.  
  426. /*
  427.  *  The following are various utility routines for general dialog management.
  428.  *  Typically, you'll want to keep them in a library that is available to all
  429.  *  your dialog modules; however, they are included here (and declared static)
  430.  *  as a private library so that you can quickly compile this file for testing.
  431.  */
  432.  
  433. #define _PrivateLibraries_
  434. #ifdef  _PrivateLibraries_
  435.  
  436. /*
  437.  *    Center a given window, w, horizontally in the main screen, top pixels from
  438.  *    the top, or centered vertically if top is 0.  The window should be invisible.
  439.  */
  440.  
  441. static void CenterWindow(WindowPtr w, int top)
  442.     {
  443.         Rect scr; Point p;
  444.         int rsize,size,margin,xoff,yoff;
  445.  
  446.         scr = qd.screenBits.bounds;
  447.         SetPort(w);
  448.         p.h = w->portRect.left; p.v = w->portRect.top;
  449.         LocalToGlobal(&p);
  450.  
  451.         size = scr.right - scr.left;
  452.         rsize = w->portRect.right - w->portRect.left;
  453.         margin = size - rsize;
  454.         if (margin > 0) {
  455.             margin >>= 1;
  456.             p.h = scr.left + margin;
  457.             }
  458.         size = scr.bottom - scr.top;
  459.         rsize = w->portRect.bottom - w->portRect.top;
  460.         margin = size - rsize;
  461.         if (margin > 0) {
  462.             margin >>= 1;
  463.             p.v = scr.top + margin;
  464.             }
  465.         MoveWindow(w,p.h,top?top:p.v,FALSE);
  466.     }
  467.  
  468. /* Local C string length routine */
  469.  
  470. static long strlen(register char *str)
  471.     {
  472.         register char *p;
  473.  
  474.         p = str;
  475.         while (*p++) ;
  476.         return((long)(--p - str));
  477.     }
  478.  
  479. /* Convert in place a Pascal string to C string, and deliver its address */
  480.  
  481. static char *PascalToC(char *str)
  482.     {
  483.         register char *p,*q,*end;
  484.  
  485.         end = str + *(unsigned char *)str;
  486.         q = (p=str) + 1;
  487.         while (p < end) *p++ = *q++;
  488.         *p = '\0';
  489.         return(str);
  490.     }
  491.  
  492. /*
  493.  *    Convert in place a C string to Pascal string, and deliver its address.
  494.  *    The C string should not be greater than 255 chars in length, or the
  495.  *    resulting Pascal string will be truncated to 255 chars.
  496.  */
  497.  
  498. static char *CToPascal(char *str)
  499.     {
  500.         register char *p,*q;
  501.         register long len;
  502.  
  503.         len = strlen(str);
  504.         if (len > 255) len = 255;
  505.         p = str + len;
  506.         q = p-1;
  507.         while (p != str) *p-- = *q--;
  508.         *str = len;
  509.         return(str);
  510.     }
  511.  
  512. /* Dialog Item Stuffers */
  513.  
  514. /*
  515.  *    Install a given Pascal string, str, into the given static or edit text item
  516.  *    in the dialog, dlog.  If the item is an edit text item, leave the installed
  517.  *    text selected or not according to the value of sel (TRUE or FALSE).
  518.  */
  519.  
  520. static void PutDlgString(DialogPtr dlog, int item, char *str, int sel)
  521.     {
  522.         short type; Handle hndl; Rect box;
  523.  
  524.         GetDItem(dlog,item,&type,&hndl,&box);
  525.         SetIText(hndl,(StringPtr)str);
  526.         if (type == editText)
  527.             SelIText(dlog,item,sel?0:32767,32767);
  528.         InvalRect(&box);
  529.     }
  530.  
  531. /*
  532.  *    Install a given decimal long value into the static or edit text item of the
  533.  *    given dialog, dlog.  If the item is an edit text item, leave the installed
  534.  *    text for the number selected or not according to sel (TRUE or FALSE).
  535.  */
  536.  
  537. static void PutDlgLong(DialogPtr dlog, int item, long val, int sel)
  538.     {
  539.         char str[32];
  540.  
  541.         NumToString(val,(StringPtr)str);
  542.         PutDlgString(dlog,item,str,sel);
  543.     }
  544.  
  545. /*
  546.  *    Same as above, only for an int (word) decimal number.
  547.  */
  548.  
  549. static void PutDlgWord(DialogPtr dlog, int item, int val, int sel)
  550.     {
  551.         PutDlgLong(dlog,item,(long)val,sel);
  552.     }
  553.  
  554. /*
  555.  *    Set the given check box or radio button item of the given dialog, dlog, to
  556.  *    on or off, according to val.
  557.  */
  558.  
  559. static void PutDlgChkRadio(DialogPtr dlog, int item, int val)
  560.     {
  561.         short type; Handle hndl; Rect box;
  562.  
  563.         GetDItem(dlog,item,&type,&hndl,&box);
  564.         SetCtlValue((ControlHandle)hndl,val!=0);
  565.     }
  566.  
  567. /*
  568.  *    Deliver the value of the checkbox or radio button item of the given dialog.
  569.  */
  570.  
  571. static int GetDlgChkRadio(DialogPtr dlog, int item)
  572.     {
  573.         short type; Handle hndl; Rect box;
  574.         
  575.         GetDItem(dlog,item,&type,&hndl,&box);
  576.         return(GetCtlValue((ControlHandle)hndl) != 0);
  577.     }
  578.  
  579. /* Dialog Item Unstuffers */
  580.  
  581. /*
  582.  *    Retrieve the value of an edit text item in a given dialog, placing the
  583.  *    resulting Pascal string in the buffer, str, which is assumed large enough
  584.  *    to hold the text (256 bytes max).  If item is the number of a static text
  585.  *    item, the empty string is delivered.  Delivers TRUE or FALSE according to
  586.  *    whether or not the text so delivered was empty.  
  587.  */
  588.  
  589. static int GetDlgString(DialogPtr dlog, int item, char *str)
  590.     {
  591.         short type; Handle hndl; Rect box;
  592.  
  593.         GetDItem(dlog,item,&type,&hndl,&box);
  594.         if (type == editText) GetIText(hndl,(StringPtr)str);
  595.          else                 *str = 0;
  596.         return(*str != 0);
  597.     }
  598.  
  599. /*
  600.  *    Retrieve the value of an edit text item in a given dialog, converting the
  601.  *    Pascal string to a long and setting *val to it.  Delivers TRUE or FALSE
  602.  *    according to whether or not the text so delivered was empty.  If FALSE,
  603.  *    *val is set to 0; if TRUE, *val is set to whatever StringToNum() says the
  604.  *    value is, even if the text contains non-numerical characters.
  605.  */
  606.  
  607. static int GetDlgLong(DialogPtr dlog, int item, long *val)
  608.     {
  609.         int ans; char str[256];
  610.  
  611.         *val = 0;
  612.         if (ans = GetDlgString(dlog,item,str))
  613.             StringToNum((StringPtr)str,val);
  614.         return(ans);
  615.         }
  616.  
  617. /* Same as above, only delivers the value of a word */
  618.  
  619. static int GetDlgWord(DialogPtr dlog, int item, short *val)
  620.     {
  621.         int ans; long num;
  622.  
  623.         *val = 0;
  624.         if (ans = GetDlgLong(dlog,item,&num))
  625.             *val = num;
  626.         return(ans);
  627.     }
  628.  
  629. /*
  630.  *    Deliver the number of the current editText item in given dialog if any text
  631.  *    is selected in it, or 0 if none selected.
  632.  */
  633.  
  634. int TextSelected(DialogPtr dlog)
  635.     {
  636.         register TEHandle textH; int item = 0;
  637.         
  638.         textH = ((DialogPeek)dlog)->textH;
  639.         if (*textH)
  640.             if ( (*textH)->selStart != (*textH)->selEnd )
  641.                 item = ((DialogPeek)dlog)->editField+1;
  642.         return(item);
  643.     }
  644.  
  645. /*
  646.  *  If any of the variable argument scrap types are available for pasting from
  647.  *  the scrap, deliver the first one.  Otherwise, deliver 0.  For example,
  648.  *    
  649.  *      if (whichType = CanPaste(3,'TEXT','PICT','STUF')) ...
  650.  *
  651.  *  There can be any number of types in the list, as long as the preceding count, n,
  652.  *  is correct.
  653.  */
  654.  
  655. static OSType CanPaste(int n, ...)
  656.     {
  657.         register OSType nextType,ans = 0L;
  658.         long err,offset;
  659.         va_list nextArg;
  660.         
  661.         va_start(nextArg,n);
  662.         nextType = va_arg(nextArg, OSType);
  663.         
  664.         while (n-- > 0) {
  665.             err = GetScrap(NIL, nextType, &offset);
  666.             if (err >= -1) {
  667.                 ans = nextType;
  668.                 break;
  669.                 }
  670.             nextType = va_arg(nextArg, OSType);
  671.             }
  672.         
  673.         va_end(nextArg);
  674.         return(ans);
  675.     }
  676.  
  677. /*
  678.  *    Frame or unframe a default dialog item (presumed a button) in given dialog.
  679.  *    Note that you don't need to use an extra user item to do this unless you
  680.  *    are doing some sort of non-standard default highlighting (not recommended).
  681.  */
  682.  
  683. static void FrameDefault(DialogPtr dlog, int item, int frame)
  684.     {
  685.         short type; Handle hndl; Rect box;
  686.         GrafPtr oldPort; PenState oldPen;
  687.         
  688.         GetPort(&oldPort); SetPort(dlog);
  689.         GetPenState(&oldPen);
  690.         
  691.         GetDItem(dlog,item,&type,&hndl,&box);
  692.         InsetRect(&box,-4,-4);
  693.         
  694.         PenSize(3,3);
  695.         if (frame) PenPat(qd.black);        /* Paint frame */
  696.          else      PenPat(qd.white);        /* Erase frame */
  697.         FrameRoundRect(&box,16,16);
  698.         
  699.         SetPenState(&oldPen);
  700.         SetPort(oldPort);
  701.     }
  702.  
  703. /*
  704.  *    Get rectangle, *panel, for a given item (usually a user or picture item)
  705.  *    and then hide the item so that it doesn't interfere with mouse clicking.
  706.  *    This lets you stop worrying about the item order any user or pict items that
  707.  *    obscure other items in the item list, which can affect how the DialogMgr
  708.  *    returns itemHits.
  709.  */
  710.  
  711. static void GetDlgPanel(DialogPtr dlog, int item, Rect *panel)
  712.     {
  713.         short type; Handle hndl;
  714.         
  715.         GetDItem(dlog,item,&type,&hndl,panel);
  716.         HideDItem(dlog,item);
  717.     }
  718.  
  719. #endif
  720.